#include "object.h"
#include "scene.h"

double PointLight::checkShade(Scene *scene, const Vec &P){
    int shadeQuality = 1;
    int shade = 0;
    for (int j = 0; j < shadeQuality; j++){
        int flag = 1;
        Vec O = getRandomLight();
        for(int i = 1 ; i <= scene->objectNum; i++){
            Vec nP, nN;
            Material nMaterial;
            Object* obj = scene->object[i];
            if ( obj->intersect( Ray(P , (O - P).normalize()), nP , nN , nMaterial) != 0 ) { //如果射线与非光源物体相碰
                if ( ( nP - P ).length() < ( O - P ).length() && (nP - P).length() > EPS) {
                    flag = 0;
                    break;
                }
            }
        }
        shade += flag;
    }
    return 1.0 * shade / shadeQuality;
}

Vec PointLight::getRandomLight()
{
    Vec light;
    do{
        light = Vec(O.x + ran() * 2 * R - R, O.y + ran() * 2 * R - R, O.z + ran() * 2 * R - R);
    }while((light - O).length() < R);
    return light;
}


double AreaLight::checkShade(Scene *scene, const Vec &P)
{
    int shade = 0;
    int shade_quality = 1;
    int gridSize = 1;
    Vec nP, nN;
    Material nMaterial;
    for (int i = -gridSize ; i < gridSize ; i++ )
        for (int j = -gridSize ; j < gridSize ; j++ )
            for (int k = 0 ; k < shade_quality ; k++ ) {
                Vec V = O + dx * ( ( ran() + i ) / gridSize ) + dy * ( ( ran() + j ) / gridSize );
                for (int t = 1; t <= scene->objectNum; t++){
                    if (scene->object[t]->intersect( Ray(P , (V - P).normalize()), nP , nN, nMaterial)) {
                        if ( ( nP - P ).length() < ( V - P ).length() && (nP - P).length() > zero) {
                            shade++;
                            break;
                        }
                    }
                }
            }

    return 1.0 - ( double ) shade / ( sqr(2.0 * gridSize) * shade_quality );
}
